/**
 * Copyright (C) 2008-2009 Cristian Olaru <colaru@gmail.com>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *         http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.integrationpath.mengine.webapp.action;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationTrustResolver;
import org.acegisecurity.AuthenticationTrustResolverImpl;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.userdetails.UserDetails;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.configuration.Configuration;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;

import com.integrationpath.mengine.model.AppUser;
import com.integrationpath.mengine.model.Article;
import com.integrationpath.mengine.model.Category;
import com.integrationpath.mengine.model.Comment;
import com.integrationpath.mengine.model.Link;
import com.integrationpath.mengine.model.LinkType;
import com.integrationpath.mengine.model.Media;
import com.integrationpath.mengine.model.MediaType;
import com.integrationpath.mengine.model.Role;
import com.integrationpath.mengine.model.Tag;
import com.integrationpath.mengine.model.Type;
import com.integrationpath.mengine.model.User;
import com.integrationpath.mengine.model.UserRole;
import com.integrationpath.mengine.model.UserRoleId;
import com.integrationpath.mengine.service.ArticleManager;
import com.integrationpath.mengine.service.GenericManager;
import com.integrationpath.mengine.service.UtilityManager;
import com.integrationpath.mengine.service.WebServicesManager;
import com.integrationpath.mengine.util.CropImage;
import com.integrationpath.mengine.util.StringUtil;
import com.integrationpath.mengine.webapp.listener.StartupListener;
import com.integrationpath.mengine.webapp.util.EngineConstants;
import com.integrationpath.mengine.webapp.util.RequestUtil;
import com.opensymphony.xwork2.Preparable;

public class ArticleAction extends BaseAction implements Preparable {
	
	Configuration configuration;
	static Logger logger = Logger.getLogger(ArticleAction.class);
	public static final java.lang.String ARTICLE_LIST = "list";
	private GenericManager<Article, Long> articleManager;
	private GenericManager<Comment, Long> commentManager;
	private GenericManager<Category, Integer> categoryManager;
	private GenericManager<Type, Integer> typeManager;
	private GenericManager<AppUser, Long> appUserManager;
	private GenericManager<Tag, Long> tagManager;
	private ArticleManager articleManagerNew;
	private GenericManager<Media, Long> mediaManager;
	private UtilityManager utilityManager;
	private GenericManager<LinkType, Integer> linkTypeManager;
	private GenericManager<Link, Integer> linkManager;

	private WebServicesManager webServicesManager;
	
	private List articles;
	private List comments;
	private List articlesTitles;
	private List articlesVoting;
	int articlesTitlesSize;
	private Article article;
	private List categories;

	private List types;
	private String tags;
	private Long id;
	private int t;
	String result = "";
	String[] tokens;
	private String tagName;
	private String categoryName;
	private String videoMedia;
	private String imagesMedia;
	private AppUser user;
	String confirmed;
	Long usersNumber;
	Media media;
	Comment comment;
	String confirmPassword;
	private List users;
	private String hash;
	private int aYear;
	private int aMonth;
	private String applicationTheme;
	
	public String getApplicationTheme() {
		return applicationTheme;
	}

	public void setApplicationTheme(String applicationTheme) {
		this.applicationTheme = applicationTheme;
	}

	public GenericManager<Link, Integer> getLinkManager() {
		return linkManager;
	}

	public void setLinkManager(GenericManager<Link, Integer> linkManager) {
		this.linkManager = linkManager;
	}

	public GenericManager<LinkType, Integer> getLinkTypeManager() {
		return linkTypeManager;
	}

	public void setLinkTypeManager(GenericManager<LinkType, Integer> linkTypeManager) {
		this.linkTypeManager = linkTypeManager;
	}

	public GenericManager<Comment, Long> getCommentManager() {
		return commentManager;
	}

	public void setCommentManager(GenericManager<Comment, Long> commentManager) {
		this.commentManager = commentManager;
	}

	public List getComments() {
		return comments;
	}

	public void setComments(List comments) {
		this.comments = comments;
	}

	public int getAYear() {
		return aYear;
	}

	public void setAYear(int year) {
		aYear = year;
	}

	public int getAMonth() {
		return aMonth;
	}

	public void setAMonth(int month) {
		aMonth = month;
	}

	public List getUsers() {
		return users;
	}

	public void setUsers(List users) {
		this.users = users;
	}

	public String getHash() {
		return hash;
	}

	public void setHash(String hash) {
		this.hash = hash;
	}

	public String getConfirmPassword() {
		return confirmPassword;
	}

	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	public Comment getComment() {
		return comment;
	}

	public void setComment(Comment comment) {
		this.comment = comment;
	}

	public Media getMedia() {
		return media;
	}

	public void setMedia(Media media) {
		this.media = media;
	}

	public Long getUsersNumber() {
		return usersNumber;
	}

	public void setUsersNumber(Long usersNumber) {
		this.usersNumber = usersNumber;
	}

	public String getConfirmed() {
		return confirmed;
	}

	public void setConfirmed(String confirmed) {
		this.confirmed = confirmed;
	}

	public GenericManager<AppUser, Long> getAppUserManager() {
		return appUserManager;
	}

	public void setAppUserManager(GenericManager<AppUser, Long> appUserManager) {
		this.appUserManager = appUserManager;
	}

	public AppUser getUser() {
		return user;
	}

	public void setUser(AppUser user) {
		this.user = user;
	}

	public String getCategoryName() {
		return categoryName;
	}

	public void setCategoryName(String categoryName) {
		this.categoryName = categoryName;
	}

	public String getVideoMedia() {
		return videoMedia;
	}

	public void setVideoMedia(String videoMedia) {
		this.videoMedia = videoMedia;
	}

	public String getImagesMedia() {
		return imagesMedia;
	}

	public void setImagesMedia(String imagesMedia) {
		this.imagesMedia = imagesMedia;
	}

	public String getTagName() {
		return tagName;
	}

	public void setTagName(String tagName) {
		this.tagName = tagName;
	}

	public List getArticlesVoting() {
		return articlesVoting;
	}

	public void setArticlesVoting(List articlesVoting) {
		this.articlesVoting = articlesVoting;
	}

	public int getArticlesTitlesSize() {
		return articlesTitlesSize;
	}

	public void setArticlesTitlesSize(int articlesTitlesSize) {
		this.articlesTitlesSize = articlesTitlesSize;
	}

	public List getArticlesTitles() {
		return articlesTitles;
	}

	public void setArticlesTitles(List articlesTitles) {
		this.articlesTitles = articlesTitles;
	}

	public int getT() {
		return t;
	}

	public void setT(int t) {
		this.t = t;
	}

	public List getTypes() {
		return types;
	}

	public void setTypes(List types) {
		this.types = types;
	}

	public GenericManager<Type, Integer> getTypeManager() {
		return typeManager;
	}

	public void setTypeManager(GenericManager<Type, Integer> typeManager) {
		this.typeManager = typeManager;
	}

	public UtilityManager getUtilityManager() {
		return utilityManager;
	}

	public void setUtilityManager(UtilityManager utilityManager) {
		this.utilityManager = utilityManager;
	}

	public GenericManager<Media, Long> getMediaManager() {
		return mediaManager;
	}

	public void setMediaManager(GenericManager<Media, Long> mediaManager) {
		this.mediaManager = mediaManager;
	}

	public GenericManager<Tag, Long> getTagManager() {
		return tagManager;
	}

	public void setTagManager(GenericManager<Tag, Long> tagManager) {
		this.tagManager = tagManager;
	}

	public String getTags() {
		return tags;
	}

	public void setTags(String tags) {
		this.tags = tags;
	}

	public ArticleManager getArticleManagerNew() {
		return articleManagerNew;
	}

	public void setArticleManagerNew(ArticleManager articleManagerNew) {
		this.articleManagerNew = articleManagerNew;
	}

	public Long getId() {
		return id;
	}

	public void setArticles(List articles) {
		this.articles = articles;
	}

	public GenericManager<Category, Integer> getCategoryManager() {
		return categoryManager;
	}

	public void setCategoryManager(
			GenericManager<Category, Integer> categoryManager) {
		this.categoryManager = categoryManager;
	}

	public List getCategories() {
		return categories;
	}

	public void setCategories(List categories) {
		this.categories = categories;
	}

	public GenericManager<Article, Long> getArticleManager() {
		return articleManager;
	}

	public void setArticleManager(GenericManager<Article, Long> articleManager) {
		this.articleManager = articleManager;
	}

	public List getArticles() {
		return articles;
	}

	public WebServicesManager getWebServicesManager() {
		return webServicesManager;
	}

	public void setWebServicesManager(WebServicesManager webServicesManager) {
		this.webServicesManager = webServicesManager;
	}

	/**
	 * Grab the entity from the database before populating with request
	 * parameters
	 */
	public void prepare() {
		
		if(configuration==null)
			configuration = (Configuration)ServletActionContext.getServletContext().getAttribute(EngineConstants.CONFIG_KEY);
		
		// set the application theme name and path - to see if is needed each time
		ServletContext servletContext = StartupListener.getAppContext();
		servletContext.setAttribute("application_theme", configuration.getProperty("application.current.theme"));
		servletContext.setAttribute("path_theme", "/themes/" + configuration.getProperty("application.current.theme").toString().toLowerCase());
		setApplicationTheme((String)configuration.getProperty("application.current.theme"));
		
		// add database bundle		
//		ResourceBundle bundle = ResourceBundle.getBundle("DatabaseResources", new Locale("en", "en"), DbResourceBundle.getMyControl(getRequest()));
//		Config.set(getRequest(), Config.FMT_LOCALIZATION_CONTEXT, new LocalizationContext(bundle, new Locale("en", "en")));
		
		if (getRequest().getMethod().equalsIgnoreCase("post")) {
			// prevent failures on new
			String articleId = getRequest().getParameter("article.id");
			if (articleId != null && !articleId.equals("")) {
				article = articleManager.get(new Long(articleId));
				article.setCategory(null);
				article.setType(null);
			}
		}
		categories = categoryManager.getAll();
		types = typeManager.getAll();
		// add categories on session
		if(getRequest().getSession().getAttribute("allCategories") == null)
			getRequest().getSession().setAttribute("allCategories",	utilityManager.getAllCategoriesOnce());
		// add types on session
		if(getRequest().getSession().getAttribute("allTypes") == null)
			getRequest().getSession().setAttribute("allTypes", types);
		// add tags on sesion
		if(getRequest().getSession().getAttribute("allTags") == null)
			getRequest().getSession().setAttribute("allTags", utilityManager.getAllTagsOnce());
//		if(getRequest().getSession().getAttribute("linkTypes") == null)
			getRequest().getSession().setAttribute("linkTypes",	linkTypeManager.getAll());
		
		addVotings();

		if (getRequest().getMethod().equalsIgnoreCase("post")) {
			// prevent failures on new
			if (!"".equals(getRequest().getParameter("user.id"))) {
				String userId = getRequest().getParameter("user.id");
				if (userId != null)
					user = appUserManager.get(new Long(userId));
			}
		}

		if(getRequest().getSession().getAttribute("usersNumber") == null)
			getRequest().getSession().setAttribute("usersNumber", utilityManager.getUsersNumber());
		String userAgent = getRequest().getHeader("User-Agent");
		if (userAgent.indexOf("MSIE 6.0") > -1 && getRequest().getSession().getAttribute("userAgent") == null)
			getRequest().getSession().setAttribute("userAgent",userAgent);

		getRequest().getSession().setAttribute("visitators", ((Map)getSession().getServletContext().getAttribute("clickstreams")).size());

		if(getRequest().getSession().getAttribute("archives") == null)
			getRequest().getSession().setAttribute("archives", articleManagerNew.getMonthsAndYears());
		if(articleManagerNew.getFeaturedArticles().size() != 0) {
			Article article = (Article)articleManagerNew.getFeaturedArticles().get(0);
			getRequest().setAttribute("minFeature", article.getId());
		}
		
		getRequest().getSession().setAttribute("lastComments", utilityManager.getLastComments(configuration.getInt("article.comments.size")));

		
		getRequest().getSession().setAttribute("blogsWidget", webServicesManager.getBlogs());
		getRequest().getSession().setAttribute("resourcesWidget", webServicesManager.getResources());
		
		setFeaturedArticles();
		
	}

	private void setFeaturedArticles() {
		List oldArticles = articleManagerNew.getFeaturedArticles();
		List featuredArticles = new ArrayList();
		for (Object object : oldArticles) {
			Article oldArticle = (Article)object;
			Article article = new Article();
			try {
				BeanUtils.copyProperties(article, oldArticle);
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			int contentLenght = oldArticle.getOverview().length();
			if(oldArticle.getOverview().length() > EngineConstants.NUMBER_OF_CHARACTERS_FOR_FEATURE_CONTENT)
				contentLenght = EngineConstants.NUMBER_OF_CHARACTERS_FOR_FEATURE_CONTENT;
				article.setOverview(truncateArticleBySize(oldArticle.getOverview(), contentLenght));
			if(oldArticle.getTitle().length() > EngineConstants.NUMBER_OF_CHARACTERS_FOR_FEATURE_TITLE)
				article.setTitle(truncateArticleBySize(oldArticle.getTitle(), EngineConstants.NUMBER_OF_CHARACTERS_FOR_FEATURE_TITLE));		
			article.setTitleLine(oldArticle.getTitle().trim()
					.replace(' ', '-'));
			featuredArticles.add(article);
		}
		
		oldArticles = null;
		getRequest().setAttribute("featuredArticles", featuredArticles);
	}
 
	public String getAllArticles() {
		setArticles(articleManager.getAll());
		return SUCCESS;
	}
	
	public String getAllUsers() {
		setUsers(appUserManager.getAll());
		return SUCCESS;
	}	
	
	public String getAllComments() {
		List comments = utilityManager.getAllComments();
		for (Object object : comments) {
			Comment comment = (Comment)object;
			comment.setContent(EngineConstants.COMMENT_CONTENT_CONVENTION + comment.getContent());
		}
		setComments(comments);
		return SUCCESS;
	}

	
	public String listByUser() {
		List articleList = null;
		// set informations if this user is autentificated
		Object obj = SecurityContextHolder.getContext().getAuthentication()
				.getPrincipal();
		String username = "";
		if (obj instanceof UserDetails) {
			Long userId = ((User) obj).getId();

			articleList = articleManagerNew.getArticlesByUser(userId);
			for (Object object : articleList) {
				Article article = (Article)object;
				article.setTitleLine(article.getTitle().trim()
						.replace(' ', '-'));
			}
			setArticles(articleList);
		}
		return SUCCESS;
	}

	public String getArticlesByUser() {
		List articleList = null;
		if (user != null) {
			articleList = articleManagerNew.getArticlesByUser(user.getId());
			setArticles(articleList);
		}
		return SUCCESS;
	}
	
	public String list() {
		Article article;
		List articleList = null;
		List totalVisibleList = new ArrayList();
		List titleVisibleList = new ArrayList();
        
		if (t == 0)
			articleList = articleManagerNew.getArticlesBySize(configuration.getInt("article.size.total"));
		else
			articleList = articleManagerNew.getArticlesByTypeAndSize(t,	configuration.getInt("article.size.total"));

		int visibleLimit = (articleList.size() < configuration.getInt("article.size.visible") ? articleList.size():configuration.getInt("article.size.visible"));
		for (int i = 0; i < visibleLimit; i++) {
			article = (Article) articleList.get(i);
			if (article != null) {
				article.setCommentsNumber(article.getComments().size());
				article.setMediasNumber(article.getMedias().size());
				Double ratingSize = utilityManager.calculateRating(article
						.getId());
				article.setRatingsNumber(ratingSize);
				totalVisibleList.add(article);
				String articleContent = article.getContent();
				article.setTitleLine(article.getTitle().trim()
						.replace(' ', '-'));
			}
		}

		for (int i = configuration.getInt("article.size.visible"); i < articleList.size(); i++) {
			article = (Article) articleList.get(i);
			if (article != null) {
				article.setCommentsNumber(article.getComments().size());
				article.setMediasNumber(article.getMedias().size());
				Double ratingSize = utilityManager.calculateRating(article
						.getId());
				article.setRatingsNumber(ratingSize);
				titleVisibleList.add(article);
				article.setTitleLine(article.getTitle().trim()
						.replace(' ', '-'));
			}
		}

		setArticles(totalVisibleList);
		setArticlesTitles(titleVisibleList);
		setArticlesTitlesSize(titleVisibleList.size());

		return SUCCESS;
	}

	private void addVotings() {
		Article article;
		List orderedList = articleManagerNew.getArticlesByVotings(configuration.getInt("article.voting.size"));
		List articlesVoting = new ArrayList();
		for (int i = 0; i < orderedList.size(); i++) {
			article = (Article) orderedList.get(i);
			Article articleVot = new Article();
			articleVot.setTitle(truncateArticleTitle(article.getTitle()));
			//articleVot.setContent(truncateArticleContent(article.getContent()));
			articleVot.setOverview(truncateArticleContent(article.getOverview()));
			articleVot.setCommentsNumber(article.getComments().size());
			articleVot.setViewsNumber(article.getViewsNumber());
			articleVot.setRatingsNumber(article.getRatingsNumber());
			articleVot.setId(article.getId());
			articleVot.setType(article.getType());
			articleVot.setTitleLine(article.getTitle().trim().replace(' ', '-'));
			articlesVoting.add(articleVot);
		}
		getRequest().setAttribute("articlesVoting", articlesVoting);
		getRequest().setAttribute("articlesVotingSize", articlesVoting.size());
	}

	public String getArticlesByCategory() {
		articles = articleManagerNew.getArticlesByCategoryName(categoryName);
		return SUCCESS;
	}

	public String getPolicyPage() {
		return SUCCESS;
	}

	public String getAboutPage() {
		return SUCCESS;
	}

	public String getForumContent() {
		return SUCCESS;
	}

	public String getArticlesByMediaType() {
		articles = articleManagerNew.getArticlesByMediaType(id.intValue());
		return SUCCESS;
	}

	public String getArticlesByTag() {
		articles = articleManagerNew.getArticlesByTagName(tagName);
		return SUCCESS;
	}

	public String getArticlesByDate() {
		articles = articleManagerNew.getArticlesByDate(aYear, aMonth);
		return SUCCESS;
	}
	
	public void setId(Long id) {
		this.id = id;
	}

	public Article getArticle() {
		return article;
	}

	public void setArticle(Article article) {
		this.article = article;
	}

	public String delete() {
		articleManager.remove(article.getId());
		saveMessage(getText("article.deleted"));

		return SUCCESS;
	}

	public String edit() {
		if (id != null) {
			article = articleManager.get(id);
			// set the tags for this article
			Set<Tag> tagList = article.getTags();
			tags = "";
			for (Iterator iterator = tagList.iterator(); iterator.hasNext();) {
				Tag tag = (Tag) iterator.next();
				tags += tag.getName() + (iterator.hasNext() ? " , " : "");
			}

			// set the media for this article
			Set<Media> mediaList = article.getMedias();
			imagesMedia = "";
			media = new Media();
			for (Iterator iterator = mediaList.iterator(); iterator.hasNext();) {
				Media anyMedia = (Media) iterator.next();
				try {
					BeanUtils.copyProperties(media, anyMedia);
				} catch (IllegalAccessException e) {
					logger.error(e);
				} catch (InvocationTargetException e) {
					logger.error(e);
				}
				if (anyMedia.getMediaType().getId() == EngineConstants.VIDEO_MEDIA) {
					setVideoMedia(anyMedia.getUrl());
				} else if (anyMedia.getMediaType().getId() == EngineConstants.IMAGE_MEDIA) {
					imagesMedia += ", " + anyMedia.getUrl();
				}
			}

			if (imagesMedia.startsWith(","))
				imagesMedia = imagesMedia.substring(1);
		} else {
			article = new Article();
		}

		return SUCCESS;
	}

	public String getArticleContent() {
		article = articleManager.get(id);	
		article.setViewsNumber(article.getViewsNumber() +1);
		articleManager.save(article);
		
		article.setCommentsNumber(article.getComments().size());
		article.setTitleComma(article.getTitle().trim().replace(' ', ','));
		getRequest().setAttribute(
				"imageMediaNr",
				utilityManager.getMediaNumberByType(
						EngineConstants.IMAGE_MEDIA, article.getId()));
		setFieldErrors((Map) getRequest().getSession().getAttribute(
				"fieldErrors"));
		setActionErrors((Collection) getRequest().getSession().getAttribute(
				"actionErrors"));
		setComment((Comment) getRequest().getSession().getAttribute("comment"));
		getRequest().getSession().setAttribute("fieldErrors", null);
		getRequest().getSession().setAttribute("actionErrors", null);
		getRequest().getSession().setAttribute("comment", null);
		
		return SUCCESS;
	}

	public String save() throws Exception {
		if (cancel != null) {
			return "cancel";
		}

		if (delete != null) {
			return delete();
		}
		if(article == null) return ARTICLE_LIST;
		boolean isNew = (article.getId() == null);

		article.setCategory(categoryManager.get(article.getCategory().getId()));
		article.setType(typeManager.get(article.getType().getId()));

		// set informations if this user is autentificated
		Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		String username = "";
		if (obj instanceof UserDetails) {
			username = ((UserDetails) obj).getUsername();
			String emaiAddress = ((User) obj).getEmail();
			article.setEmaiAddress(emaiAddress);
			AppUser appUser = appUserManager.get(((User) obj).getId());
			article.setAppUser(appUser);
		} else {
			username = obj.toString();
//			return ARTICLE_LIST;
		}

		article.setNickname(username);
		
		// remove old tags for this article
		Set oldTags = article.getTags();
		Tag[] atags = (Tag[]) oldTags.toArray(new Tag[1]);

		for (int i = 0; i < atags.length; i++) {
			Tag articleTag = (Tag) atags[i];
			article.getTags().remove(articleTag);
			if (articleTag != null)
				tagManager.remove(articleTag.getId());
		}

		// add new tags for this article
		String[] tagList = tags.split(",");
		Set articleTags = new HashSet();
		for (int i = 0; i < tagList.length; i++) {
			String tag = tagList[i].trim();
			Tag localTag = new Tag();
			localTag.setName(tag);
			localTag.setArticle(article);
			articleTags.add(localTag);
		}

		// save tags for this article
		article.setTags(articleTags);

		// remove old medias for this article
		Set oldMedias = article.getMedias();

		Media[] amedias = (Media[]) oldMedias.toArray(new Media[1]);

		for (int i = 0; i < amedias.length; i++) {
			Media articleMedia = (Media) amedias[i];
			article.getMedias().remove(articleMedia);
			if (articleMedia != null)
				mediaManager.remove(articleMedia.getId());
		}

		if (!getVideoMedia().equals("")) {
			// save medias for this article
			Media videoMedia = new Media();
			BeanUtils.copyProperties(videoMedia, media);
			videoMedia.setUrl(getVideoMedia());
			MediaType videoMediaType = new MediaType();
			videoMediaType.setId(EngineConstants.VIDEO_MEDIA);
			videoMedia.setMediaType(videoMediaType);
			videoMedia.setArticle(article);
			article.getMedias().add(videoMedia);
		}

		if (!getImagesMedia().equals("")) {
			Image image = null;
			String[] medias = imagesMedia.split(",");
			MediaType imageMediaType = new MediaType();
			imageMediaType.setId(EngineConstants.IMAGE_MEDIA);
			for (int i = 0; i < medias.length; i++) {
				Media imageMedia = new Media();
				BeanUtils.copyProperties(imageMedia, media);
				String media = medias[i].trim();
				imageMedia.setUrl(media);
				imageMedia.setMediaType(imageMediaType);
				imageMedia.setArticle(article);

				// add thumb nail to the database
				
		        String x = getRequest().getParameter("x");
		        String y = getRequest().getParameter("y");
		        String w = getRequest().getParameter("w");
		        String h = getRequest().getParameter("h");
		        
		        if(x.equals("") || y.equals("") || w.equals("") || h.equals("")) {
		        	x = "0";
		        	y = "0";
		        	w = "224";
		        	h = "152";
		        }
		        
		        URL url = new URL(media);
		        image = ImageIO.read(url);
		        
		        // crop image 
		        Toolkit tk = Toolkit.getDefaultToolkit();		         
		        ImageProducer source = image.getSource();
		        
		        ImageFilter extractFilter = new CropImageFilter(
		        		new Integer(x),
		        		new Integer(y),
		        		new Integer(w),
		        		new Integer(h));		
		        
		        Image image2 = tk.createImage(new FilteredImageSource(source,extractFilter));


		        BufferedImage img = CropImage.toBufferedImage(image2);
		        ByteArrayOutputStream bas = new ByteArrayOutputStream();
		        ImageIO.write(img, "gif", bas);
		        byte[] data = bas.toByteArray();
		        
		        article.setThumbnail(data);
		        
		      
				article.getMedias().add(imageMedia);				
			}
		}

		if (isNew) {
			// set the article status
			article.setStatus(EngineConstants.ARTICLE_DISABLED);
			article.setFeatured(EngineConstants.ARTICLE_UNFEATURED);
			article.setDate(new Date());
			article.setViewsNumber(new Long(0));
			article.setRatingsNumber(new Double(0));
			String emailSubject = getText("article.form.email.subject", new String[] { username, article.getTitle()});
			String emailBody = getText("article.form.email.body", new String[] {username, article.getOverview()});
			AppUser adminUser = appUserManager.get(1L);
			utilityManager.sendMailToUser(emailSubject, emailBody, adminUser, getRequest(), getText("prifile.confirm.reply"));
		}
		
		Article savedArticle = articleManager.save(article);

		String key = (isNew) ? "article.added" : "article.updated";
		saveMessage(getText(key));
	
		
		if (!isNew) {
			return INPUT;
		} else {
			return SUCCESS;
		}
	}

	/**
	 * To be simplified Grab the user from the database based on the "id" passed
	 * in.
	 * 
	 * @return success if user found
	 * @throws IOException
	 *             can happen when sending a "forbidden" from
	 *             response.sendError()
	 */
	public String editUserProfile() throws IOException {
		HttpServletRequest request = getRequest();

		// if a user's id is passed in
		if (id != null) {
			// lookup the user using that id
			user = appUserManager.get(id);
		} else {
			user = new AppUser();
		}

		// if user logged in with remember me, display a warning that they can't
		// change passwords
		log.debug("checking for remember me login...");

		AuthenticationTrustResolver resolver = new AuthenticationTrustResolverImpl();
		SecurityContext ctx = SecurityContextHolder.getContext();

		if (ctx != null) {
			Authentication auth = ctx.getAuthentication();

			if (resolver.isRememberMe(auth)) {
				getSession().setAttribute("cookieLogin", "true");
				saveMessage(getText("userProfile.cookieLogin"));
			}
		}
		return SUCCESS;
	}

	public String saveUserProfile() throws Exception {
		// sent mail to new user for enabling it's acount
		String algorithm = (String) getConfiguration().get(
				EngineConstants.ENC_ALGORITHM);
		if (algorithm == null) { // should only happen for test case
			log.debug("assuming testcase, setting algorithm to 'SHA'");
			algorithm = "SHA";
		}
		String userPassword = StringUtil.encodePassword(user.getPassword(),
				algorithm);

		boolean isNew = (user.getId() == null);
		if (!isNew)
			user.setAccountEnabled(true);
		else {
			user.setAccountEnabled(false);
			String webappName = getText("webapp.name");
			String emailSubject = getText("profile.confirm.subject",  new String[] {webappName});
			String emailBody = getText("profile.confirm.body", new String[] {webappName, RequestUtil.getAppURL(getRequest()), userPassword });
			utilityManager.sendMailToUser(emailSubject, emailBody, user,
					getRequest(), getText("webapp.office.mail"));
		}

		user.setPassword(userPassword);
		user = appUserManager.save(user);

		// set the role for this user

		Role role = roleManager.getRole(EngineConstants.USER_ROLE);
		UserRole userRole = new UserRole();
		userRole.setAppUser(user);
		UserRoleId userRoleId = new UserRoleId();
		userRoleId.setRoleId(role.getId());
		userRoleId.setUserId(user.getId());
		userRole.setId(userRoleId);
		user.getUserRoles().add(userRole);
		appUserManager.save(user);

		String key = (isNew) ? "profile.added" : "profile.updated";
		saveMessage(getText(key));

		return SUCCESS;
	}

	public String confirmAccount() {
		users = appUserManager.getAll();
		for (Iterator iterator = users.iterator(); iterator.hasNext();) {
			AppUser type = (AppUser) iterator.next();
			String userHash = type.getPassword();
			log.info(hash + "|" + userHash);
			if (hash.equals(userHash)) {
				log.info("User is ok to be eanbled with hash: " + hash);
				type.setAccountEnabled(true);
				appUserManager.save(type);
				String webappSite = getText("webapp.site");
				String emailAddress = getText("webapp.office.mail");
				String emailSubject = getText("profile.user.confirmation.subject", new String[] {webappSite});
				String emailBody = getText("profile.user.confirmation.body", new String[] {webappSite, emailAddress });
				utilityManager.sendMailToUser(emailSubject, emailBody, type,
						getRequest(), getText("prifile.confirm.reply"));
			}
		}
		saveMessage(getText("account.confirmed"));
		getRequest().getSession().setAttribute("confirmed",
				getText("logo.confirmed"));

		return list();
	}

	private String truncateArticleTitle(String content) {
		int realLenght = EngineConstants.NUMBER_OF_CHARACTERS_FOR_TITLE < content
				.length() ? EngineConstants.NUMBER_OF_CHARACTERS_FOR_TITLE
				: content.length();
		// boolean isComplete =
		// content.length()<=EngineConstants.NUMBER_OF_CHARACTERS_FOR_TITLE;
		result = content.substring(0, realLenght);
		result = result.replaceAll("<p>", "");
		result = result.replaceAll("</p>", "");
		int lastWord = result.lastIndexOf(' ');
		if(lastWord != -1)
			result = result.substring(0, lastWord);
		// if(!isComplete)
		result = result + "...";
		return result;
	}

	private String truncateArticleContent(String content) {
		result = content
				.substring(
						0,
						(EngineConstants.NUMBER_OF_CHARACTERS_FOR_CONTENT < content
								.length() ? EngineConstants.NUMBER_OF_CHARACTERS_FOR_CONTENT
								: content.length()));
		result = result.replaceAll("<p>", "");
		result = result.replaceAll("</p>", "");
		int lastWord = result.lastIndexOf(' ');
		if(lastWord != -1)
			result = result.substring(0, lastWord);
		return result + "...";
	}

	private String truncateArticleBySize(String content, int size) {
		int realLenght = size < content
				.length() ? size
				: content.length();
		result = content.substring(0, realLenght);
		result = result.replaceAll("<p>", "");
		result = result.replaceAll("</p>", "");
		int lastWord = result.lastIndexOf(' ');
		if(lastWord != -1)
			result = result.substring(0, lastWord);
		// if(!isComplete)
		result = result + "...";
		return result;
	}
	
	private String truncateArticleTitleByWords(String content) {
		tokens = content.split(" ");
		result = "";
		int contentLength = Math.min(EngineConstants.NUMBER_OF_WORDS_FOR_TITLE,
				tokens.length);
		for (int i = 0; i < contentLength; i++) {
			result = result + " " + tokens[i];
		}
		result = result.replaceAll("<p>", "");
		result = result.replaceAll("</p>", "");
		return result + "...";
	}

	private String truncateArticleContentByWords(String content) {
		tokens = content.split(" ");
		result = "";
		int contentLength = Math.min(
				EngineConstants.NUMBER_OF_WORDS_FOR_CONTENT, tokens.length);
		for (int i = 0; i < contentLength; i++) {
			result = result + " " + tokens[i];
		}
		result = result.replaceAll("<p>", "");
		result = result.replaceAll("</p>", "");
		return result + "...";
	}

	@Override
	public void validate() {
		boolean isNew = (user != null && user.getId() == null);
		getActionErrors().clear();
		// validate the email and nickname
		if (user != null && isNew) {
			if (utilityManager.isEmailInDatabase(user.getEmail())) {
				addActionError(getText("profile.email.in.database"));
			}

			if (utilityManager.isUseridInDatabase(user.getUsername())) {
				addActionError(getText("profile.userid.in.database"));
			}
		}
	}
	
	public String comfyTest() {
		System.out.println("Just a test");
		return SUCCESS;
	}
}